/*
 * Copyright (C) 2012 Rothens
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package rpg;

import java.awt.image.BufferedImage;
import java.util.HashMap;
import rpg.gfx.Bitmap;
import rpg.util.ImageUtil;

/**
 * rothens.tarhely.biz
 * @author Rothens
 */
public class Tiles {

	public HashMap<Character, Tile> landscape;
	public HashMap<Character, RoadTile> roads;
	public HashMap<Character, Tile> layer1;
	public HashMap<Character, Tile> layer2;
	public Tile naTile;

	public class Tile {

		public char name;
		public boolean passable = true;
		public boolean transparent = true;
		public Bitmap bitmap;

		public Tile(BufferedImage img, char name) {
			bitmap = new Bitmap(img.getWidth(), img.getHeight());
			this.name = name;


			img.getRGB(0, 0, bitmap.width, bitmap.height, bitmap.pixels, 0, bitmap.width);

		}

		public Tile(BufferedImage img, char name, int row, int col) {
			bitmap = new Bitmap(64, 64);
			this.name = name;
			img.getSubimage(col * 64, row * 64, 64, 64).getRGB(0, 0, bitmap.width, bitmap.height, bitmap.pixels, 0, bitmap.width);;

		}

		public Tile(BufferedImage img, char name, boolean pass) {
			this(img,name);
			this.passable = pass;

		}

		public Tile(BufferedImage img, char name, int row, int col, boolean pass) {
			this(img,name,row,col);
			this.passable = pass;
		}
		
		public Tile setTransparent(boolean to){
			transparent = to;
			return this;
		}
	}

	/**
	 * This is the "adopting" version of a tile. This is a tile with 9 different tile-pictures.
	 */
	public class MultiTile extends Tile {
		/*
		 * 0 1 2
		 * 3 4 5
		 * 6 7 8
		 */

		Bitmap[] bitmaps;

		public MultiTile(BufferedImage img, char name) {
			super(img, name);
			bitmaps = new Bitmap[9];

			for (int row = 0; row < 3; row++) {
				for (int col = 0; col < 3; col++) {
					int i = col + row * 3;
					bitmaps[i] = new Bitmap(64, 64);
					for (int j = 0; j < 64 * 64; j++) {

						int r = j / 64;
						int c = j % 64;
						bitmaps[i].pixels[j] = bitmap.pixels[(col * 64 + c) + (row * bitmap.width * 64) + r * bitmap.width];
					}
				}
			}

		}
	}

	public class RoadTile implements Cloneable{

		private Character name;
		public Bitmap[] bitmaps;
		private int state = 0;

		public RoadTile(Character name, BufferedImage bfImg) {
			this.name = name;
			createBitmaps(bfImg);
		}
		
		public RoadTile(RoadTile from){
			name = from.name;
			bitmaps = from.bitmaps;
			state = from.state;
		}

		@Override
		public Object clone() throws CloneNotSupportedException {
			return super.clone();
		}
		
		public int getState(){
			return state;
		}
		
		public void setState(int state){
			this.state = state;
		}
		
		public Character getName(){
			return name;
		}

		private void createBitmaps(BufferedImage bfImg) {
			bitmaps = new Bitmap[16];
			bitmaps[0] = ImageUtil.getSub(bfImg, 0, 5); //o
			bitmaps[8] = ImageUtil.getSub(bfImg, 0, 0); //[-
			bitmaps[1] = bitmaps[8].rotate();
			bitmaps[2] = bitmaps[1].rotate();
			bitmaps[4] = bitmaps[2].rotate();
			
			
			bitmaps[10] = ImageUtil.getSub(bfImg, 0, 1); //-
			bitmaps[5] = bitmaps[10].rotate();
			bitmaps[15] = ImageUtil.getSub(bfImg, 0, 2); //+
			bitmaps[14] = ImageUtil.getSub(bfImg, 0, 3); //T
			bitmaps[13] = bitmaps[14].rotate();
			bitmaps[11] = bitmaps[13].rotate();
			bitmaps[7] = bitmaps[11].rotate();
			bitmaps[6] = ImageUtil.getSub(bfImg, 0, 4); //L
			bitmaps[12] = bitmaps[6].rotate();
			bitmaps[9] = bitmaps[12].rotate();
			bitmaps[3] = bitmaps[9].rotate();
		}

		
	}

	public void loadTiles() {

		BufferedImage tileSet = ImageUtil.createImageIcon("/res/tileset.png");

		//used for unknown characters in the map
		naTile = new Tile(tileSet, '%', 1, 2);

		landscape = new HashMap<Character, Tile>();
		landscape.put('g', new Tile(tileSet, 'g', 0, 0)); //grass
		landscape.put('~', new Tile(tileSet, '~', 0, 1, false)); //water
		landscape.put('d', new Tile(tileSet, 'd', 0, 2)); //dirt
		landscape.put('s', new Tile(tileSet, 's', 1, 0)); //sand
		landscape.put('l', new Tile(tileSet, 'l', 1, 1, false)); //lava

		BufferedImage layer1Set = ImageUtil.createImageIcon("/res/bushes.png");
		layer1 = new HashMap<Character, Tile>();
		layer1.put('1', new Tile(layer1Set, '1', 0, 0, false).setTransparent(false));
		layer1.put('2', new Tile(layer1Set, '2', 0, 1, false).setTransparent(false));
		layer1.put('3', new Tile(layer1Set, '3', 0, 2, false).setTransparent(false));
		layer1.put('4', new Tile(layer1Set, '4', 1, 0, false).setTransparent(false));
		layer1.put('5', new Tile(layer1Set, '5', 1, 1, false).setTransparent(false));
		layer1.put('6', new Tile(layer1Set, '6', 1, 2, false).setTransparent(false));
		layer1.put('7', new Tile(layer1Set, '7', 2, 0, false).setTransparent(false));

		layer2 = new HashMap<Character, Tile>();
		layer2.put('1', new Tile(layer1Set, '1', 2, 1));
		layer2.put('2', new Tile(layer1Set, '2', 2, 2));

		BufferedImage road1 = ImageUtil.createImageIcon("/res/road.png");
		roads = new HashMap<Character, RoadTile>();
		roads.put('1', new RoadTile('1', road1));
	}

	/**
	 * Get the assigned tile
	 * @param c character
	 * @return the tile, or water if not found.
	 */
	public Tile getTile(char c) {
		return (landscape.get(c) != null) ? landscape.get(c) : naTile;
	}

	/**
	 * Get the assigned layer1 element
	 * @param c character
	 * @return the tile, or null if not found.
	 */
	public Tile getLayer1(char c) {
		return layer1.get(c);
	}

	public Tile getLayer2(char c) {
		return layer2.get(c);
	}

	public RoadTile getRoad(char c) {
		return roads.get(c);
	}
}
